package com.example.license.create;

import com.example.license.entity.LicenseCheckModel;
import com.example.license.entity.LicenseCreatorParam;
import de.schlichtherle.license.*;
import lombok.extern.slf4j.Slf4j;

import javax.security.auth.x500.X500Principal;
import java.io.*;
import java.util.*;
import java.util.prefs.Preferences;

/**
 * CreateLicense 生成证书
 */
@Slf4j
public class CreateLicense {
    //common param
    private static String PRIVATEALIAS = "";
    private static String KEYPWD = "";
    private static String STOREPWD = "";
    private static String SUBJECT = "";
    private static String licPath = "";
    private static String priPath = "";
    //license content
    private static Date issuedTime = null;
    private static Date notBefore = null;
    private static Date notAfter = null;
    private static String consumerType = "";
    private static int consumerAmount = 0;
    private static String info = "";
    private static Map<String,Object> licenseCheckModelMap = null;
    // 为了方便直接用的API里的例子
    // X500Princal是一个证书文件的固有格式，详见API
    private final static X500Principal DEFAULTHOLDERANDISSUER =
            new X500Principal("CN=guanshi, OU=guanshi, O=guanshi, L=china, ST=china, C=china");

    public void setParam(String propertiesPath, LicenseCreatorParam param) {
        // 获取配置参数
        Properties prop = new Properties();
        InputStream in = getClass().getResourceAsStream(propertiesPath);
        try {
            prop.load(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
        PRIVATEALIAS = prop.getProperty("PRIVATEALIAS");
        STOREPWD = prop.getProperty("STOREPWD");
        SUBJECT = prop.getProperty("SUBJECT");
        KEYPWD = prop.getProperty("KEYPWD");
        //证书生成地址
        licPath = prop.getProperty("licPath");
        priPath = prop.getProperty("priPath");
        //license content
        issuedTime = param.getIssuedTime();
        notBefore = param.getNotBeforeTime();
        notAfter = param.getNotAfterTime();
        Map<String,Object> map=new HashMap<>();
        map.put("ipAddress",param.getLicenseCheckModel().getIpAddress());
        map.put("macAddress",param.getLicenseCheckModel().getMacAddress());
        map.put("userNum",param.getLicenseCheckModel().getUserNum());
        map.put("clientNum",param.getLicenseCheckModel().getClientNum());
        licenseCheckModelMap=map;
        consumerType = prop.getProperty("consumerType");
        consumerAmount = Integer.valueOf(prop.getProperty("consumerAmount"));
        info = prop.getProperty("info");
    }

    // 返回生成证书时需要的参数
    private static LicenseParam initLicenseParams() {
        Preferences preference = Preferences.userNodeForPackage(CreateLicense.class);
        // 设置对证书内容加密的对称密码
        CipherParam cipherParam = new DefaultCipherParam(STOREPWD);
        // 参数1,2从哪个Class.getResource()获得密钥库;参数3密钥库的别名;参数4密钥库存储密码;参数5密钥密码
        KeyStoreParam privateStoreParam = new DefaultKeyStoreParam(
                CreateLicense.class, priPath, PRIVATEALIAS, STOREPWD, KEYPWD);
        // 返回生成证书时需要的参数
        LicenseParam licenseParams =  new DefaultLicenseParam(SUBJECT,
                preference, privateStoreParam, cipherParam);
        return licenseParams;
    }

    // 通过外部配置文件构建证书的的相关信息
    public final static LicenseContent createLicenseContent() {
        LicenseContent content = new LicenseContent();
        content.setSubject(SUBJECT);
        content.setHolder(DEFAULTHOLDERANDISSUER);
        content.setIssuer(DEFAULTHOLDERANDISSUER);
        //发布日期
        content.setIssued(issuedTime);
        //有效开始日期
        content.setNotBefore(notBefore);
        //有效结束日期
        content.setNotAfter(notAfter);
        //自定义扩展扩展 mac地址 用户数
        content.setExtra(licenseCheckModelMap);
        content.setConsumerType(consumerType);
        content.setConsumerAmount(consumerAmount);
        content.setInfo(info);
        return content;
    }

    public void create() throws Exception {
            /************** 证书发布者端执行 ******************/
            log.info("创建证书开始");
            LicenseManager licenseManager = LicenseManagerHolder.getLicenseManager(initLicenseParams());
            licenseManager.store((createLicenseContent()), new File(licPath));
            log.info("创建证书成功");
    }

}